import { HierarchicalStateMachine } from "framework/FSM/HierarchicalStateMachine";
import { AIControllFactory } from "./ControlManager/FSMFactory/AIController";
import { ActionManager } from "./ControlManager/Control/ActionManager/ActionManager";
import { EntityType, ExucuteType, IEntity } from "GameLoop/WorldState/EntityManager/Entitys/Entity.interface";
import { WorldState } from "GameLoop/WorldState/worldstate";
import { BehaviorMask } from "GameLoop/WorldState/WorldConfig";
import { AITeamFactory } from "./ControlManager/FSMFactory/FSMTeam/AITeamFactory";
import { handle_moves } from "GameLoop/WorldState/mount/move/Kuhn-Munkres";
import { UpdateResult } from "framework/FSM/HSMBase";
 
const executedEntity:EntityType[]=[
    "SpawnEntity",
    "TeamUpgrader",
    "Team4",
    "Team2",
    "Team9"
]
/**
 * 提供实体的创建方法。
 * 还有实体的执行
 */
/*@profile*/
export class WorkManager
{
    private actionManager:ActionManager;
 
    private controls:Record<ExucuteType,HierarchicalStateMachine>={} as any;
    constructor()
    {
        this.actionManager = new ActionManager();
    }
    /**
     * 初始化
     */
    public init()
    {
        this.controls["Room"] = AIControllFactory.CreateRoomController();
        this.controls["TeamUpgrader"] = AIControllFactory.CreateTeamUpgrade();
        this.controls["Team2"] = AITeamFactory.CreateTeam2();
        this.controls["Team4"] = AITeamFactory.CreateTeam4();
        this.controls["Team9"] = AITeamFactory.CreateTeam4();
        this.controls["Creep"] = AIControllFactory.CreateCreepController();
        this.controls["InnerMineEntity"] = AIControllFactory.CreateInnerMineController();
        this.controls["SpawnEntity"] = AIControllFactory.CreateSpawnController();
        this.controls["PowerCreep"] = AIControllFactory.CreatePowerCreepController();
    }
    public run(world:WorldState)
    {
         
        // 0.team run 以flag为单位进行控制
        // 1.pc run 
        // 2.creep run
        // 3.room run 
        this.actionManager.actionStart();
        this.executeRoom(world);
        this.executeEntity(world);
        this.executePowerCreep();
        this.executeCreep()
        
        
      
        // 4.entity组的执行、
       
        // pc的执行
        
      

        // 爬虫的执行
        this.actionManager.actionEnd();
        handle_moves();
        // this.actionManager.executeActions();
    }
    private executeRoom(world:WorldState)
    {
        for(let k of global.resourceStats.myrooms)
        {
            if(Game.rooms[k].getType() == 1&& Game.rooms[k].controller?.my)
            {
                // Game.rooms[k].log(`info`,`执行房间${k}的AI`);
                this.executeAI("Room",Game.rooms[k]);
            }
           
        }
    }
    private executeEntity(world:WorldState)
    {
        for(const roomName in world.EntityDB.Entities)
        {
            if(!Game.rooms[roomName].controller?.my)
            {
                global.Log.Error(`room ${roomName} 实体执行错误!房间控制器已经不是我的，但是依旧在执行实体逻辑`);
                continue;
            }
            for(const t of executedEntity)
            // for(const   type in world.EntityDB.Entities[roomName])
            {
                if(world.EntityDB.Entities[roomName][t])
                {
                    for(const e of world.EntityDB.Entities[roomName][t])
                    {         
                        this.executeAI(t as ExucuteType,e);
                    }
                }
                
            }
        }
    }
    private executePowerCreep()
    {
        for(let k in Game.powerCreeps)
        {
            this.executeAI("PowerCreep",Game.powerCreeps[k]);
        }
    }

    private executeCreep()
    {
        for(let k in Game.creeps)
        {
            const creep = Game.creeps[k];
            const room = Game.creeps[k].ownerRoom();
            if(room && room.controller?.my && creep.isSpawned()  )
            {
                if(!creep.memory.teamid || (creep.memory.teamid && creep.memory.BoostLevel && !creep.memory.IsBoosted))
                {
                    const cpu = Game.cpu.getUsed();
                    const rets = this.executeAI("Creep",creep);
                    const cpu2 = Game.cpu.getUsed();

                    if(cpu2- cpu >1 && (cpu2- cpu)-creep.memory.Debug['move']>1)
                    {
                        global.Log.Info(`creep[${creep.ticksToLive}] ${JSON.stringify(creep.pos)} ${creep.name} 行为用时 ${cpu2- cpu}`,`移动用时${creep.memory.Debug['move']}`,`路由用时${creep.memory.Debug['route']}`);
                        if((cpu2- cpu) > 4)
                        {
                           
                            const log = (rets as any).actions?((rets as any).actions    as IActionCMD<"transfer">[]).map(e=> {
                                return `${ e.key}`}).join('_'):'';
                            // Memory.Debug[`mem${creep.name}`] = creep.memory;
                           global.Log.Warning(JSON.stringify(creep.room.getTaskById(creep.memory.taskid!,["creep"])),log );
                        //    if((rets as any).actions)
                        //    {
                        //         Memory.Debug[`task${creep.name}`] = (rets.actions as IActionCMD<"transfer">[]).map(e=>{
                        //         const v = _.cloneDeep(e);
                        //           v.arg.entity = undefined as any;
                        //         return v.key;
                        //        });
                        //    }
                          
                        }
                    }
                    // else 
                    // {
                    //     creep.log('warn',`  ${creep.name} 行为用时 ${cpu2- cpu}`,`移动用时${creep.memory.Debug['move']}`);
                    // }
                }   
            }
        }
    }
    private getEntityAi(type:string)
    {
        if(!this.controls[type as ExucuteType])
        {
            throw new Error(`${type}  未定义 逻辑 状态机`);
        }
        return this.controls[type as ExucuteType]
    }

    public executeAI(type:ExucuteType,entity:IEntity)
    {
        if(type== "Creep")
        {
            let code = this.actionManager.executeAction(entity.GUID())
            if(code)
            {
                const  cpu1 = Game.cpu.getUsed();
                //{
                    const ai = this.getEntityAi(type);
                    if(entity.getNodeMemory().hsm)
                    {
                        ai.resetState(entity.getNodeMemory().hsm);
                    }
                    const ret =ai.Update({entity:entity}); 
                    this.actionManager.pushAction(entity.GUID(),ret.actions as IActionCMD[]);
                    this.actionManager.executeAction(entity.GUID())
                    entity.getNodeMemory().hsm = (ai.getStateStack());
                //}
                const  cpu2 = Game.cpu.getUsed();
                return ret;
                // if(code ==2)
                // {
                //     global.Log.Error(`新分配action 队列 cpu 消耗 ${(entity as Creep).ticksToLive} ${(entity as Creep).spawning} cpu[${cpu2-cpu1}]`)
                // }
            }
            return new UpdateResult()
        }
        else 
        {
            const ai = this.getEntityAi(type);
            if(entity.getNodeMemory().hsm)
            {
                ai.resetState(entity.getNodeMemory().hsm);
            }
            // global.Log.Info(entity.GUID());
            const ret =ai.Update({entity:entity});
            // if((entity as Creep)?.memory?.Role=="idaRed")
            // {
            //     this.printState(ai,entity);
            // }

            if(entity.GUID()== Memory.Debug['debugCreep'])
            {
               this.printState(ai,entity);
            }
            this.actionManager.pushAction(entity.GUID(),ret.actions as IActionCMD[]);
            this.actionManager.executeAction(entity.GUID())
            entity.getNodeMemory().hsm = (ai.getStateStack());
            return ret;
        }
    }

    private printState(ai:HierarchicalStateMachine<IStateArg<IGameEntity>>,entity:IEntity)
    {
        const states =ai.getStates();
        const components_state =ai.getComponentsState();
        entity.log("info",`  ${JSON.stringify( _.map(states,item=>item.constructor.name))} `);
         if(components_state.length>0)
         {
            entity.log("info",`子状态机状态  ${_.map(components_state,e=>JSON.stringify( _.map(e,item=>item.constructor.name))).concat("--")}`)
         }
    }
}